package com.yaodian100.ec.activity.service.impl;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.springframework.beans.factory.annotation.Autowired;

import com.yaodian100.core.common.dao.impl.CommonCriteria;
import com.yaodian100.core.common.exception.CoreException;
import com.yaodian100.core.common.utils.DateUtil;
import com.yaodian100.core.common.utils.ServerValue;
import com.yaodian100.core.template.service.TemplateService;
import com.yaodian100.ec.activity.entity.ActivityPage;
import com.yaodian100.ec.activity.entity.ActivityPageBlock;
import com.yaodian100.ec.activity.entity.ActivityPageBlockTemplate;
import com.yaodian100.ec.activity.entity.ActivityStyle;
import com.yaodian100.ec.activity.service.ActivityPageBlockService;
import com.yaodian100.ec.activity.service.ActivityPageBlockTemplateService;
import com.yaodian100.ec.activity.service.ActivityPageGenerateService;
import com.yaodian100.ec.activity.service.ActivityPageService;
import com.yaodian100.ec.activity.service.ActivityStyleService;

public class ActivityPageGenerateServiceImpl implements ActivityPageGenerateService {
	public static final String WEB_PATH = "act/pm/system/";
	private static final String OUTPUT_PATH = "system/act/pm/";
	private static final String OUTPUT_HEAD_FILE = "/pages/header/head.html";
	private static final String OUTPUT_HEADER_FILE = "/pages/header/header_act.html";
	@Autowired
	private ActivityPageService activityPageService;
	@Autowired
	private ActivityPageBlockService activityPageBlockService;
	@Autowired
	private ActivityStyleService activityStyleService;
	@Autowired
	private TemplateService templateServcie;
	@Autowired
	private ActivityPageBlockTemplateService activityPageBlockTemplateService;
	
	private String encoding = "utf-8";
	private static final String UTF8_BOM = "\uFEFF";
	private static final String OUTPUT_ROOT = ServerValue.getMidHtmlPath();
	
	@Override
	public String generate(ActivityPage activityPage) throws CoreException {
		String datePath = DateUtil.convertDateToString("yyyyMMdd", activityPage.getExpectedOnlineDate());
		String outputPath = OUTPUT_ROOT + OUTPUT_PATH + datePath;
		String outputFileName = datePath + "-" + activityPage.getCustomFileName() + ".html";
		File outputFile = new File(outputPath,outputFileName);
		outputFile.getParentFile().mkdirs();
		
		FileOutputStream out = null;
		try {
			out = new FileOutputStream(outputFile);
			this.generate(activityPage, out, true);
		} catch (Exception e) {
			e.printStackTrace();
			throw new CoreException("ActivityPageGenerateService:"+e.getMessage(),e);
		} finally {
			try {
				out.close();
			} catch (Exception e) {}
		}
		//return "/" + OUTPUT_PATH + datePath + "/" + outputFileName;
		return "/" + WEB_PATH + datePath + "/" + outputFileName;
	}
	
	@Override
	public String generate(Long activityPageId) throws CoreException {
		ActivityPage page = this.activityPageService.get(activityPageId);
		return this.generate(page);
	}
	
	@Override
	public void generate(Long activityPageId, OutputStream out) throws CoreException {
		ActivityPage page = this.activityPageService.get(activityPageId);
		if (out == null) {
			this.generate(page);
		} else {
			this.generate(page, out, true);
		}
	}

	@Override
	public void preview(ActivityPage activityPage, OutputStream out) throws CoreException {
		this.generate(activityPage, out, false);
	}
	
	@Override
	public void generate(ActivityPage activityPage, OutputStream out) throws CoreException {
		this.generate(activityPage, out, true);
	}
	
	private void generate(ActivityPage activityPage, OutputStream out,boolean ssiEnable) throws CoreException {
		if (activityPage == null) return;
		
		List<ActivityPageBlock> blocks = this.getActivityPageBlocks(activityPage.getId());
		ActivityStyle activityStyle = this.activityStyleService.get(activityPage.getStyleId());
		
		Map<String,Object> contentMap = new HashMap<String,Object>();
		contentMap.put("ActivityPage", activityPage);
		contentMap.put("basehref", ServerValue.getFrontHostname());
		contentMap.put("contextpath", ServerValue.getFrontContextPath());
		contentMap.put("uploadImagePath",ActivityPageService.MAIN_VISUAL_IMAGE_WEB_PATH );
		contentMap.put("blocks", blocks);
		contentMap.put("style", activityStyle);
		contentMap.put("systime", new Date().getTime());
		
		if (activityPage.getExpectedOnlineDate() == null) {
			activityPage.setExpectedOnlineDate(new Date());
		}
		
		if (activityPage.getMainVisualContentType() == 3) {
			contentMap.put("htmlFileContent", this.getHtmlContent(activityPage.getMainVisualHtmlFilePath()));
		}
		
		if (!ssiEnable) {
			//contentMap.put("previewHead", this.getHtmlContent(ServerValue.getFrontHostname() + "/" + OUTPUT_HEAD_FILE));
			contentMap.put("previewHeader", this.getHtmlContent(ServerValue.getFrontHostname() + "/" + OUTPUT_HEADER_FILE));
		}
		
		String page = this.templateServcie.format("activityPage", contentMap);
		
//		System.out.println(page);
		try {
			out.write(page.getBytes("utf-8"));
		} catch (Exception e) {
			e.printStackTrace();
			throw new CoreException("ActivityPageGenerateService:"+e.getMessage(),e);
		}
	}
	
	private String getHtmlContent(String url) {
		HttpClient client = new HttpClient();
		GetMethod method = new GetMethod(url);
		method.addRequestHeader("Content-Type", "text/html; charset=" + encoding);
		method.addRequestHeader("Cache-control", "no-cache");
		method.addRequestHeader("Pragma","no-cache");
		method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler(3, false));
		try {
			int status = client.executeMethod(method);
			if (status != HttpStatus.SC_OK) {
				System.out.println("Load fail : " + method.getStatusLine());
				return "";
			}
			byte[] b = new byte[1024];
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			BufferedInputStream bis = new BufferedInputStream(method.getResponseBodyAsStream());
			int len = 0;
			while ((len = bis.read(b, 0, 1024)) != -1) {
				baos.write(b, 0, len);
			}

			baos.flush();
			
			String content = baos.toString(encoding);
			if (content.startsWith(UTF8_BOM)) {
				content = content.substring(1);
			}
			return content;
		} catch (Exception e) {
			e.printStackTrace();
			return "";
		} finally {
			method.releaseConnection();
		}


	}
	
	private List<ActivityPageBlock> getActivityPageBlocks(long pageId) {
		CommonCriteria c = new CommonCriteria();
		c.addEq("pageId", pageId);
		String[] sortOrder = new String[] {"sortOrder asc"};
		
		return this.activityPageBlockService.getList(0, -1, c, sortOrder);
	}

	public ActivityPageService getActivityPageService() {
		return activityPageService;
	}

	public void setActivityPageService(ActivityPageService activityPageService) {
		this.activityPageService = activityPageService;
	}

	public TemplateService getTemplateServcie() {
		return templateServcie;
	}

	public void setTemplateServcie(TemplateService templateServcie) {
		this.templateServcie = templateServcie;
	}

	public ActivityPageBlockService getActivityPageBlockService() {
		return activityPageBlockService;
	}

	public void setActivityPageBlockService(
			ActivityPageBlockService activityPageBlockService) {
		this.activityPageBlockService = activityPageBlockService;
	}


	public ActivityPageBlockTemplateService getActivityPageBlockTemplateService() {
		return activityPageBlockTemplateService;
	}


	public void setActivityPageBlockTemplateService(
			ActivityPageBlockTemplateService activityPageBlockTemplateService) {
		this.activityPageBlockTemplateService = activityPageBlockTemplateService;
	}


	public ActivityStyleService getActivityStyleService() {
		return activityStyleService;
	}


	public void setActivityStyleService(ActivityStyleService activityStyleService) {
		this.activityStyleService = activityStyleService;
	}

	
}
